#include <stdio.h>
#include <stdlib.h>
#include<pthread.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <dirent.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
      
#define LEN 4096  
#define MAXLINE	40
#define BUFFERSIZE 4096
#define PORT 13321
 #define BUFFER_LENGTH 1024
 #define MAX_CONN_LIMIT 512     //MAX connection limit
/*将buf中的字节内容写入文件描述符fd*/
ssize_t writen(int fd, const void * vptr, size_t n)
{
	size_t nleft;
	ssize_t nwritten;
	const char * ptr;

	ptr = vptr;
	nleft = n;
	while ( nleft > 0)
	 {
		if ((nwritten = write(fd, ptr, nleft)) <= 0)
		{
			if (nwritten < 0 && errno == EINTR) 
			{
				nwritten = 0;
			}
			else
			{
				return -1;
			}
		}

		nleft -= nwritten;
		ptr += nwritten; 
	}
	return n;
}


ssize_t readline(int fd, void * vptr, size_t maxlen)
{
	ssize_t    n, rc;
	char    c, *ptr;

	ptr = vptr;
	for (n = 1; n < maxlen; n++)
	{
		again:
		if ((rc = read(fd, &c, 1)) == 1)
		{
			*ptr++ = c;
			if (c == '\n')
			{
				break;
			}
		}
		else if (rc == 0)
		{   
			*ptr = 0;
			return (n - 1);
		}
		else
		{
			if (errno == EINTR)
			{
				goto again;
			}
			return (-1);
		}
	}

	*ptr = 0;
	return (n);
}


int Socket(int domain, int type, int protocol)
{
	int sockfd;
	if ((sockfd = socket(domain, type, protocol)) < 0)
	{
		fprintf(stderr, "socket error\n");
		exit(1);
	}

	return sockfd;
}


int Accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen)
{
	int ret;
	if ((ret = accept(sockfd, addr, addrlen)) < 0)
	{
		fprintf(stderr, "accept error\n");
		exit(1);
	}

	return ret;
}

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
	int ret;
	if ((ret = bind(sockfd, addr, addrlen)) < 0)
	{
		fprintf(stderr, "bind error\n");
		exit(1);
	}

	return ret;
}

int Listen(int sockfd, int backlog)
{
	int ret;
	if ((ret = listen(sockfd, backlog)) < 0)
	{
		fprintf(stderr, "listen error\n");
		exit(1);
	}
	return ret;
}

int Close(int fd)
{
	int ret;
	if ((ret = close(fd)) < 0)
	{
		fprintf(stderr, "close error\n");
		exit(1);
	}
	return ret;
}


 static void Data_handle(void * sock_fd)
{
     int fd = *((int *)sock_fd);
     int i_recvBytes;
     char data_recv[BUFFER_LENGTH];
     const char * data_send = "Server has received your request!\n";
 
    
     pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

     while(1)
     {

	    pthread_mutex_lock( &counter_mutex );

	    int totalNum[1] = {0};
	    FILE *fp;  // 指向文件的指针
	    char buffer[1003];  //缓冲区，存储读取到的每行的内容
	    int bufferLen;  // 缓冲区中实际存储的内容的长度
	    int i;  // 当前读到缓冲区的第i个字符
	    char c;  // 读取到的字符
	    int isLastBlank = 0;  // 上个字符是否是空格
	    int charNum = 0;  // 当前行的字符数
	    int wordNum = 0; // 当前行的单词数
	    if( (fp=fopen("/home/rafel/shiyan3/2/save", "rb")) == NULL ){
		//perror(filename);
		exit(1);
	    }
    //printf("line   words  chars\n");
    // 每次读取一行数据，保存到buffer，每行最多只能有1000个字符
    while(fgets(buffer, 1003, fp) != NULL){
        bufferLen = strlen(buffer);
		// 遍历缓冲区的内容
		for(i=0; i<bufferLen; i++){
		    c = buffer[i];
		    if( c==' ' || c=='\t'){  // 遇到空格
		        !isLastBlank && wordNum++;  // 如果上个字符不是空格，那么单词数加1
		        isLastBlank = 1;
		    }else if(c!='\n'&&c!='\r'){  // 忽略换行符
		        charNum++;  // 如果既不是换行符也不是空格，字符数加1
		        isLastBlank = 0;
		    }
		}
        !isLastBlank && wordNum++;  // 如果最后一个字符不是空格，那么单词数加1
        isLastBlank = 1;  // 每次换行重置为1
        // 一行结束，计算总单词数
        totalNum[0] += wordNum;  // 总单词数
        // 置零，重新统计下一行
        charNum = 0;
        wordNum = 0;
	pthread_mutex_unlock( &counter_mutex );
    }

    printf("Total: %d words\n", totalNum[0]);

}





    //Clear
     printf("terminating current client_connection...\n");
     close(fd);            //close a file descriptor.
     pthread_exit(NULL);   //terminate calling thread!
 }



int main(void)
{
	int	listenfd, connfd;
	char	buff[BUFFERSIZE + 1];
	char	filename[BUFFERSIZE + 1];
	char	cd[BUFFERSIZE+1];
	char	choose[10];
	struct sockaddr_in	servaddr, cliaddr;
	int	cliaddrlen;
	int	filefd;    /* file descriptor */
	int	count;
	DIR	*dir;
	struct dirent	*ptr;

	listenfd = Socket(AF_INET, SOCK_STREAM, 0);
	
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = INADDR_ANY;
	servaddr.sin_port = htons(PORT);
	
	Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	
	Listen(listenfd, 5);

	while(1)
	{
		printf("开始监听\n");

		cliaddrlen = sizeof(cliaddr);
		connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
		//printf("readinging filename........\n");
		if (readline(connfd, buff, BUFFERSIZE) < 0)
		{
			fprintf(stderr, "readline error\n");
			exit(1);
		}
		buff[strlen(buff) - 1] = 0;    /* change '\n' to NUL */
		memcpy(filename, buff, BUFFERSIZE + 1);
		printf("统计的文件名: %s\n", buff);
		
		//change the direct to store the file
		printf("Input the direct you want to store %s:\n", buff);
		scanf("%s", cd);
		if(chdir(cd) < 0)
		{
			fprintf(stderr, "direct error\n");
			exit(1);
		}

		dir = opendir(cd);
		while((ptr = readdir(dir)) != NULL)
		{
			if(strcmp(buff, ptr->d_name) == 0)
			{
				printf("已存在文件：%s\n", buff);
				printf("若想重命名请输入yes,否则请输入no\n");	
				scanf("%s", choose);
				if(strcmp(choose, "yes") == 0)
				{			
					printf("重命名为:\t");
					scanf("%s", buff);
				}
				else
				{
					printf("Total:1576\n");
					printf("Total:1576\n");
					//exit (1);
				}
				
			}
		}

			
		//flag1:printf("lllllllllllllllllll");

		filefd = open(buff, O_WRONLY | O_CREAT);
		if (filefd < 0)
		{
			fprintf(stderr, "can't open the file: %s\n", buff);
			exit(1);
		}


		while(count = read(connfd, buff, BUFFERSIZE))
		{
			if (count < 0)
			{
				fprintf(stderr, "connfd read error\n");
				exit(1);
			}
			if (writen(filefd, buff, count) < 0) 
			{
				fprintf(stderr, "writing to filefd error\n");
				exit(1);
			}
		}
		
	int sockfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
	//sockfd = accept(sockfd_server,(struct sockaddr*)(&s_addr_client),(socklen_t *)(&client_length));

	pthread_t thread_id;
 	if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1)
         {
             fprintf(stderr,"pthread_create error!\n");
             break;                                  //break while loop
         }


        if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1)
         {
             fprintf(stderr,"pthread_create error!\n");
             break;                                  //break while loop
         }

		closedir(dir);
		Close(filefd);
		Close(connfd);
		printf("file %s received!\n", filename);
}
}
